/* linkit.js
 * By François Leporcq
 * MIT Licensed.
 */
var PolyLink = AbstractLink.extend({
    _className: "PolyLink",
    init: function(startPolygon, endPolygon, startLabel, endLabel, midLabel, start, end){
        this._start = start != null ? start : new Anchor();
        this._end = end != null ? end : new Anchor();
        this._line = new Polyline(new Array(this._start, this._end));
        this._startPolygon = startPolygon;
        this._endPolygon = endPolygon;
        this._startLabel = startLabel;
        this._endLabel = endLabel;
        this._midLabel = midLabel;
        this.setShapes(this.getShapes());
        this._updateStartPolygon();
        this._updateEndPolygon();
        this._updateStartLabel();
        this._updateEndLabel();
        this._updateMidLabel();
    },

    setStart: function(start){
        this._start = start;
        this._line.setPointAt(start,0);
        this._addMidPoints();
        this._updateStartPolygon();
        this._updateEndPolygon();
        this._updateStartLabel();
        this._updateMidLabel();
    },
    setEnd: function(end){
        this._end = end;
        this._line.setPointAt(end,this._line.getPoints().length - 1);
        this._addMidPoints();
        this._updateStartPolygon();
        this._updateEndPolygon();
        this._updateEndLabel();
        this._updateMidLabel();
    },
    _addMidPoints: function(){
        this._removeMidPoints();
        if(ECardinalPoint.areOpposite(this._start.getCardinalPoint(), this._end.getCardinalPoint())){
            var pointAfterStart = this._getMidPoint(this._start, 2);
            var pointBeforeEnd = this._getMidPoint(this._end, 2);
            this._line.addPointAt(pointAfterStart,1);
            this._line.addPointAt(pointBeforeEnd,2);
        }else{
            var pointAfterStart = this._getMidPoint(this._start, 1);
            this._line.addPointAt(pointAfterStart,1);
        }
    },
    _getMidPoint:function(anchor, midPointsCount){
        var width = Math.abs(this._end.getX() - this._start.getX());
        var height = Math.abs(this._end.getY() - this._start.getY());
        var point = new Point();
        switch (anchor.getCardinalPoint()){
            case ECardinalPoint.NORTH:
                point.setX(anchor.getX());
                point.setY(anchor.getY() + height / midPointsCount);
                break;
            case ECardinalPoint.EAST:
                point.setX(anchor.getX() + width / midPointsCount);
                point.setY(anchor.getY());
                break;
            case ECardinalPoint.SOUTH:
                point.setX(anchor.getX());
                point.setY(anchor.getY() - height / midPointsCount);
                break;
            case ECardinalPoint.WEST:
                point.setX(anchor.getX() - width / midPointsCount);
                point.setY(anchor.getY());
                break;
        }
        return point;
    },
    _updateStartPolygon: function(){
        if(this._startPolygon != null && this._start != null && this._end != null){
            this._startPolygon.setOrigin(this._start);
            this._startPolygon.resetRotation();
            var line = new Line(this._start,this._line.getPointAfter(this._start));
            this._startPolygon.rotate(270-line.getXAxisTheta());
        }
    },
    _updateEndPolygon: function(){
        if(this._endPolygon != null && this._end != null && this._end != null){
            this._endPolygon.setOrigin(this._end);
            this._endPolygon.resetRotation();
            var line = new Line(this._line.getPointBefore(this._end),this._end);
            this._endPolygon.rotate(90-line.getXAxisTheta());
        }
    },
    _removeMidPoints: function(){
        this._line.removePointsBetween(0, this._line.getPoints().length - 1);
        this._updateStartPolygon();
        this._updateEndPolygon();
    },
    //@Override
    _updateStartLabel: function(){
        this._super();
        if(this._startLabel != null && this._start != null && this._end){
            var origin = this._startLabel.getOrigin();
            var x = origin.getX();
            var y = origin.getY();
            var width = this._startLabel.getWidth();
            var height = this._startLabel.getHeight();
            var cardinalPoint = this._start.getCardinalPoint();
            if(cardinalPoint == ECardinalPoint.EAST || cardinalPoint == ECardinalPoint.WEST){
                y = this._start.getY() - (height / 2);
            }else if(cardinalPoint == ECardinalPoint.NORTH || cardinalPoint == ECardinalPoint.SOUTH){
                x = this._start.getX() - (width / 2);
            }
            this._startLabel.setOrigin(new Point(x, y));
        }
    },
    //@Override
    _updateEndLabel: function(){
        this._super();
        if(this._endLabel != null && this._start != null && this._end){
            var origin = this._endLabel.getOrigin();
            var x = origin.getX();
            var y = origin.getY();
            var width = this._endLabel.getWidth();
            var height = this._endLabel.getHeight();
            var cardinalPoint = this._end.getCardinalPoint();
            if(cardinalPoint == ECardinalPoint.EAST || cardinalPoint == ECardinalPoint.WEST){
                y = this._end.getY() - (height / 2);
            }else if(cardinalPoint == ECardinalPoint.NORTH || cardinalPoint == ECardinalPoint.SOUTH){
                x = this._end.getX() - (width / 2);
            }
            this._endLabel.setOrigin(new Point(x, y));
        }
    }

});